const _ = require('lodash');
const config = require('../config');
const fse = require('fs-extra');
const JsonIO = require('./utils/jsonio');
const Renderer = require('./utils/renderer');

const adocInfoIO = new JsonIO(config.dbPath);
const tagRenderer = new Renderer(`${config.templateDir}/tag.hbs`);
const tagsRenderer = new Renderer(`${config.templateDir}/tags.hbs`);

class TagToPosts {
  constructor() {
    this.map = {};
  }

  put(tag, post) {
    if (!this.map[tag]) {
      this.map[tag] = [];
    }
    this.map[tag].push(post);
  }

  get() {
    return this.map;
  }

  isEmpty() {
    return _.isEmpty(this.map);
  }
}

module.exports = async () => {
  const adocInfo = adocInfoIO.read();
  const adocList = _.values(adocInfo);

  const tagToPosts = new TagToPosts();
  adocList.forEach((post) => {
    const tags = post.tags || [];
    tags.forEach((tag) => {
      const trimedTag = _.trim(tag);
      tagToPosts.put(trimedTag, post);
    });
  });

  if (tagToPosts.isEmpty()) return;

  await Promise.all(
    _(tagToPosts.get())
      .keys()
      .map((tagName) => {
        const orderedAdocList = _.orderBy(tagToPosts.get()[tagName], 'date', 'desc');
        const html = tagRenderer.render({
          adocList: orderedAdocList,
          tagName,
          nav: config.site.nav,
          logo: config.site.logo
        });
        return fse.outputFile(`${config.deployDir}/tag/${tagName}.html`, html);
      })
      .value()
  );

  const tagsHtml = tagsRenderer.render({
    tags: _(tagToPosts.get())
      .mapValues((posts, tagName) => ({ size: Math.min(36, posts.length * 2 + 14), tagName }))
      .values()
      .value(),
    nav: config.site.nav,
    logo: config.site.logo,
    analysis: config.site.analysis
  });
  return fse.outputFile(`${config.deployDir}/tags.html`, tagsHtml);
};
